﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.IO;
using System.Web.Hosting;

namespace OpenWaves.ImageTransformations.Web
{
    public class MapPathBasedFileStore : IFileStore
    {
        private readonly UrlPath storeVirtualPath;

        public MapPathBasedFileStore(UrlPath storeVirtualPath)
        {
            Contract.Requires<ArgumentNullException>(storeVirtualPath != null);

            this.storeVirtualPath = storeVirtualPath;

            EnsureVirtualPathExists(this.storeVirtualPath);
        }

        public Url GetFileUrl(string fileName)
        {
            return this.GetFileVirtualPath(fileName).ToUrl();
        }

        private UrlPath GetFileVirtualPath(string fileName)
        {
            return this.storeVirtualPath.Combine(fileName);
        }

        public bool FileExists(string fileName)
        {
            return File.Exists(MapPath(this.GetFileVirtualPath(fileName)));
        }

        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "FxCop is stupid!")]
        public Stream CreateFile(string fileName)
        {
            return File.Create(MapPath(this.GetFileVirtualPath(fileName)));
        }

        public void DeleteFile(string fileName)
        {
            //exception is not thrown when file does not exist. Other exceptions (like SecurityException) are thrown
            //http://msdn.microsoft.com/en-us/library/system.io.file.delete%28v=VS.100%29.aspx

            File.Delete(MapPath(this.GetFileVirtualPath(fileName)));
        }

        private static string MapPath(UrlPath virtualPath)
        {
            return HostingEnvironment.MapPath(virtualPath.ToString());
        }

        private static void EnsureVirtualPathExists(UrlPath virtualPath)
        {
            var storePathRoot = MapPath(virtualPath);
            if (Directory.Exists(storePathRoot) == false)
                Directory.CreateDirectory(storePathRoot);
        }
    }
}